﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;

namespace AzukiMapUI
{
    [TemplatePart(Name = PopupWindow.ElementTitleBarName, Type = typeof(FrameworkElement))]
    [TemplatePart(Name = PopupWindow.ElementStatusBarName, Type = typeof(FrameworkElement))]
    [TemplatePart(Name = PopupWindow.ElementWindowBorderName, Type = typeof(Border))]
    [TemplatePart(Name = PopupWindow.ElementButtonsName, Type = typeof(Panel))]
    [TemplatePart(Name = PopupWindow.ElementContentContainerName, Type = typeof(Border))]
    [TemplatePart(Name = PopupWindow.ElementCloseButtonName, Type = typeof(Button))]
    [TemplatePart(Name = PopupWindow.ElementResizeImageName, Type = typeof(FrameworkElement))]
    [TemplatePart(Name = PopupWindow.ElementModalMaskName, Type = typeof(Rectangle))]
    public class PopupWindow : DragDropControl
    {
        #region Fields

        private const string ElementTitleBarName = "TitleBar";
        private const string ElementButtonsName = "Buttons";

        protected Button ElementCloseButton { get; set; }
        private const string ElementCloseButtonName = "CloseButton";

        protected Border ElementContentContainer { get; set; }
        private const string ElementContentContainerName = "ContentContainer";

        protected Border ElementWindowBorder { get; set; }
        private const string ElementWindowBorderName = "WindowBorder";

        protected FrameworkElement ElementResizeImage { get; set; }
        private const string ElementResizeImageName = "ResizeImage";

        protected FrameworkElement ElementStatusBar { get; set; }
        private const string ElementStatusBarName = "StatusBar";

        protected Rectangle ElementModalMask { get; set; }
        private const string ElementModalMaskName = "ModalMask";

        #endregion

        #region IsModal

        /// <summary>
        /// Identifies the IsModal dependency property.
        /// </summary>
        public static readonly DependencyProperty IsModalProperty = DependencyProperty.Register("IsModal", typeof(bool), typeof(PopupWindow), null);

        /// <summary>
        /// Gets or sets the IsModal possible Value of the bool object.
        /// </summary>
        public bool IsModal
        {
            get { return (bool)GetValue(IsModalProperty); }
            set { SetValue(IsModalProperty, value); }
        }
        #endregion IsModal

        #region ShowStatus

        /// <summary>
        /// Identifies the ShowStatus dependency property.
        /// </summary>
        public static readonly DependencyProperty ShowStatusProperty = DependencyProperty.Register("ShowStatus", typeof(bool), typeof(PopupWindow), null);

        /// <summary>
        /// Gets or sets the ShowStatus possible Value of the bool object.
        /// </summary>
        public bool ShowStatus
        {
            get { return (bool)GetValue(ShowStatusProperty); }
            set { SetValue(ShowStatusProperty, value); }
        }
        #endregion ShowStatus

        #region Title

        /// <summary>
        /// Identifies the Title dependency property.
        /// </summary>
        public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(PopupWindow), null);

        /// <summary>
        /// Gets or sets the Title possible Value of the string object.
        /// </summary>
        public string Title
        {
            get { return (string)GetValue(TitleProperty); }
            set { SetValue(TitleProperty, value); }
        }

        #endregion Title

        #region TitleBackground

        /// <summary>
        /// Identifies the TitleBackground dependency property.
        /// </summary>
        public static readonly DependencyProperty TitleBackgroundProperty = DependencyProperty.Register("TitleBackground", typeof(Brush), typeof(PopupWindow), null);

        /// <summary>
        /// Gets or sets the TitleBackground possible Value of the Brush object.
        /// </summary>
        public Brush TitleBackground
        {
            get { return (Brush)GetValue(TitleBackgroundProperty); }
            set { SetValue(TitleBackgroundProperty, value); }
        }
        #endregion TitleBackground

        #region Status

        /// <summary>
        /// Identifies the Status dependency property.
        /// </summary>
        public static readonly DependencyProperty StatusProperty = DependencyProperty.Register("Status", typeof(string), typeof(PopupWindow), new PropertyMetadata(OnStatusPropertyChanged));

        /// <summary>
        /// Gets or sets the Status possible Value of the string object.
        /// </summary>
        public string Status
        {
            get { return (string)GetValue(StatusProperty); }
            set { SetValue(StatusProperty, value); }
        }

        /// <summary>
        /// StatusProperty property changed handler.
        /// </summary>
        /// < param name="d">PopupWindow that changed its Status.</param>
        /// < param name="e">DependencyPropertyChangedEventArgs.</param>
        private static void OnStatusPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var _PopupWindow = d as PopupWindow;
            if (_PopupWindow != null)
            {
                //TODO: Handle new value.
            }
        }
        #endregion Status

        #region Constructor
        public PopupWindow()
        {
            this.DefaultStyleKey = typeof(PopupWindow);
            this.CanResize = true;
            this.ShowStatus = false;
        }
        #endregion

        #region Overrides

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            this.ElementWindowBorder = GetTemplateChild(ElementWindowBorderName) as Border;

            this.ElementCloseButton = this.GetTemplateChild(ElementCloseButtonName) as Button;
            if (this.ElementCloseButton != null)
                this.ElementCloseButton.Click += OnCloseClick;

            this.ElementContentContainer = this.GetTemplateChild(ElementContentContainerName) as Border;
            if (this.ElementContentContainer != null)
                this.ElementContentContainer.MouseLeftButtonDown += OnContentLeftButtonDown;

            this.ElementResizeImage = this.GetTemplateChild(ElementResizeImageName) as FrameworkElement;
            if (this.ElementResizeImage != null && !this.CanResize)
                this.ElementResizeImage.Visibility = Visibility.Collapsed;

            this.ElementStatusBar = this.GetTemplateChild(ElementStatusBarName) as FrameworkElement;
            if (this.ElementStatusBar != null && !this.ShowStatus)
            {
                RowDefinition r = this.GetTemplateChild("StatusRow") as RowDefinition;
                if (r != null)
                    r.MaxHeight = 0;
                this.ElementStatusBar.Visibility = Visibility.Collapsed;
            }

            if (this.IsModal)
            {
                this.ElementModalMask = this.GetTemplateChild(ElementModalMaskName) as Rectangle;
                this.Dispatcher.BeginInvoke(ShowMask);
            }
        }

        void OnCloseClick(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        void OnContentLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
        }

        //protected override Size ArrangeOverride(Size finalSize)
        //{            
        //    Size s = base.ArrangeOverride(finalSize);
        //    return s;
        //}	

        #endregion

        public void Close()
        {
            if (this.ElementModalMask != null)
            {
                this.ElementModalMask.Visibility = Visibility.Collapsed;
            }
            this.Visibility = Visibility.Collapsed;
        }

        void ShowMask()
        {
            if (this.IsModal && this.ElementModalMask != null)
            {
                var p = this.Parent as Panel;
                if (p != null)
                {
                    var g = p as Grid;
                    if (g != null)
                    {
                        if (g.ColumnDefinitions.Count > 1)
                            this.ElementModalMask.SetValue(Grid.ColumnSpanProperty, g.ColumnDefinitions.Count);
                        if (g.RowDefinitions.Count > 1)
                            this.ElementModalMask.SetValue(Grid.RowSpanProperty, g.RowDefinitions.Count);
                    }
                    this.ElementRoot.Children.Remove(this.ElementModalMask);
                    p.Children.Add(ElementModalMask);
                    this.ElementModalMask.SetValue(Canvas.ZIndexProperty, DragDropControl.MaxZIndex);
                    DragDropControl.MaxZIndex++;
                    this.SetValue(Canvas.ZIndexProperty, DragDropControl.MaxZIndex);
                    DragDropControl.MaxZIndex++;
                }
            }
        }
    }
}